package cn.wolfcode.business.bpmninfo.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;

import cn.wolfcode.business.bpmninfo.domain.vo.BusBpmnInfoVO;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.bpmninfo.mapper.BusBpmnInfoMapper;
import cn.wolfcode.business.bpmninfo.domain.BusBpmnInfo;
import cn.wolfcode.business.bpmninfo.service.IBusBpmnInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

/**
 * 流程定义明细Service业务层处理
 * 
 * @author wolfcode
 * @date 2023-06-03
 */
@Service
@Transactional
public class BusBpmnInfoServiceImpl implements IBusBpmnInfoService 
{
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;

    @Autowired
    private RepositoryService repositoryService;
    /**
     * 查询流程定义明细
     * 
     * @param id 流程定义明细主键
     * @return 流程定义明细
     */
    @Override
    public BusBpmnInfo selectBusBpmnInfoById(Long id)
    {
        return busBpmnInfoMapper.selectBusBpmnInfoById(id);
    }

    /**
     * 查询流程定义明细列表
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 流程定义明细
     */
    @Override
    public List<BusBpmnInfo> selectBusBpmnInfoList(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.selectBusBpmnInfoList(busBpmnInfo);
    }

    /**
     * 新增流程定义明细
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int insertBusBpmnInfo(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.insertBusBpmnInfo(busBpmnInfo);
    }

    /**
     * 修改流程定义明细
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int updateBusBpmnInfo(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.updateBusBpmnInfo(busBpmnInfo);
    }

    /**
     * 批量删除流程定义明细
     * 
     * @param ids 需要删除的流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBusBpmnInfoByIds(Long[] ids)
    {
        return busBpmnInfoMapper.deleteBusBpmnInfoByIds(ids);
    }

    /**
     * 删除流程定义明细信息
     * 
     * @param id 流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBusBpmnInfoById(Long id)
    {
        BusBpmnInfo info = busBpmnInfoMapper.selectBusBpmnInfoById(id);
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(info.getProcessDefinitionKey())
                .processDefinitionVersion(info.getVersion().intValue())
                .singleResult();
        repositoryService.deleteDeployment(processDefinition.getDeploymentId(),true);
        return busBpmnInfoMapper.deleteBusBpmnInfoById(id);
    }

    @Override
    public void deploy(MultipartFile file, BusBpmnInfoVO busBpmnInfoVO) throws IOException {
        Assert.notNull(file,"非法操作");
        Assert.notNull(busBpmnInfoVO,"非法操作");
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if(!"bpmn".equalsIgnoreCase(extension)){
            throw new RuntimeException("文件必须是bpmn类型");
        }
        Deployment deployment = repositoryService.createDeployment()
                .addInputStream(busBpmnInfoVO.getBpmnLabel(), file.getInputStream())
                .deploy();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        BusBpmnInfo info = new BusBpmnInfo();
        BeanUtils.copyProperties(busBpmnInfoVO,info);
        info.setDeployTime(deployment.getDeploymentTime());
        info.setProcessDefinitionKey(processDefinition.getKey());
        info.setVersion(processDefinition.getVersion() + 0L);
        busBpmnInfoMapper.insertBusBpmnInfo(info);
    }

    @Override
    public InputStream getProcess(Long id, String type) {
        Assert.notNull(id,"非法操作");
        Assert.notNull(type,"非法操作");
        BusBpmnInfo info = busBpmnInfoMapper.selectBusBpmnInfoById(id);
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(info.getProcessDefinitionKey())
                .processDefinitionVersion(info.getVersion().intValue())
                .singleResult();
        InputStream inputStream = null;
        if("xml".equalsIgnoreCase(type)){
            inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), info.getBpmnLabel());
        } else {
            DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
            BpmnModel model = repositoryService.getBpmnModel(processDefinition.getId());
            inputStream = generator.generateDiagram(model, Collections.EMPTY_LIST, Collections.EMPTY_LIST,
                    "宋体", "宋体", "宋体");
        }
        return inputStream;
    }
}
